<?php

namespace App\Models\Plane\Rules;

use App\Trip\Plane\CarrierCode;
use App\Trip\Traits\ModelDateTrait;
use Eloquent;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

/**
 * App\Models\Plane\Rules\PlaneChangeRules
 *
 * @property int         $id
 * @property string      $carrier_code 航司二字码
 * @property string      $company_name 航空公司名称
 * @property string      $cabin_name 舱位名称
 * @property string      $cabin_code 舱位code
 * @property string      $airport_code 机场code
 * @property string      $airport_name 机场
 * @property string      $ticket_type 机票客票类型
 * @property string      $start 小时 小于
 * @property string      $end 小时 大于等于
 * @property string      $rule_desc 描述
 * @property string      $rate 收费金额或费率 -1 不允许 -2  依据产品规则执行 免费 免费1次
 * @property string      $discount 折扣
 * @property string      $child_rate 收费金额或费率 -1 不允许 -2  依据产品规则执行 免费 免费1次
 * @property int         $modify  可签转 1 不可签转 2
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @method static Builder|PlaneChangeRule newModelQuery()
 * @method static Builder|PlaneChangeRule newQuery()
 * @method static Builder|PlaneChangeRule query()
 * @method static Builder|PlaneChangeRule whereAirportCode($value)
 * @method static Builder|PlaneChangeRule whereAirportName($value)
 * @method static Builder|PlaneChangeRule whereCabinCode($value)
 * @method static Builder|PlaneChangeRule whereCabinName($value)
 * @method static Builder|PlaneChangeRule whereCarrierCode($value)
 * @method static Builder|PlaneChangeRule whereChildRate($value)
 * @method static Builder|PlaneChangeRule whereCompanyName($value)
 * @method static Builder|PlaneChangeRule whereCreatedAt($value)
 * @method static Builder|PlaneChangeRule whereDiscount($value)
 * @method static Builder|PlaneChangeRule whereEnd($value)
 * @method static Builder|PlaneChangeRule whereId($value)
 * @method static Builder|PlaneChangeRule whereModify($value)
 * @method static Builder|PlaneChangeRule whereRate($value)
 * @method static Builder|PlaneChangeRule whereRuleDesc($value)
 * @method static Builder|PlaneChangeRule whereStart($value)
 * @method static Builder|PlaneChangeRule whereTicketType($value)
 * @method static Builder|PlaneChangeRule whereUpdatedAt($value)
 * @mixin Eloquent
 */
class PlaneChangeRule extends Model
{
    use HasFactory, ModelDateTrait;

    protected $table = "plane_change_rules";
    protected $fillable
                     = [
            'carrier_code',
            'company_name',
            'cabin_name',
            'cabin_code',
            'airport_code',
            'airport_name',
            'ticket_type',
            'start',
            'end',
            'rule_desc',
            'rate',
            'child_rate',
            'discount',
            'modify',
        ];

    public function add(array $data)
    {
        if ($rule = $this->findByUnique($data)) {
            Log::error("变更规则已存在,{$data['carrier_code']},{$data['company_name']},{$data['cabin_name']},{$data['cabin_code']},{$data['start']},{$data['end']},{$data['rate']},{$data['modify']},{$data['ticket_type']},{$data['airport_name']},{$data['discount']}");
            return $rule;
        }
        return $this->create($data);
    }

    private function findByUnique($data)
    {
        return $this
            ->where('carrier_code', $data['carrier_code'])
            ->where('company_name', $data['company_name'])
            ->where('cabin_name', $data['cabin_name'])
            ->where('cabin_code', $data['cabin_code'])
            ->where('start', $data['start'])
            ->where('end', $data['end'])
            ->where('rate', $data['rate'])
            ->where('discount', $data['discount'])
            ->where('modify', $data['modify'])
            ->where('ticket_type', $data['ticket_type'])
            ->where('airport_name', $data['airport_name'])
            ->first();
    }

    /**
     * @throws Exception
     */
    public function findOneByCabin(string $flight_no, string $cabin): ?self
    {
        $carrier_code = CarrierCode::getCarrierCode($flight_no);
        $cache_key    = "PlaneChangeRule:{$carrier_code}:{$cabin}";
        if (Cache::has($cache_key)) {
            return Cache::get($cache_key);
        }
        $rule = $this->where('carrier_code', $carrier_code)
                     ->where('cabin_code', $cabin)
                     ->first();
        // 如果未找到对应的规则
        if (!$rule) {
            $rule = $this->where('carrier_code', $carrier_code)
                         ->where('cabin_code', '')
                         ->first();
        }
        Cache::put($cache_key, $rule, config('trip.ttl.day') * 30);
        return $rule;
    }

    /**
     * @throws Exception
     */
    public function findByCabin(string $flight_no, string $cabin): Collection
    {
        $carrier_code = CarrierCode::getCarrierCode($flight_no);
        return $this->where('carrier_code', $carrier_code)
                    ->where('cabin_code', $cabin)
                    ->get();
    }

    public function isNotAllow(): bool
    {
        return $this->rate == '不允许';
    }

    public function isNotEnsure(): bool
    {
        return $this->rate == '依据产品规则执行';
    }
}
